//
//  ArcGraphView.m
//  HypERLtrace
//
//  Created by Vladimir Sarpe on 29/07/08.
//  Copyright 2008 __MyCompanyName__. All rights reserved.
///

#import "ArcGraphView.h"


@implementation ArcGraphView

- (void) initPart {
	found = 0;
	overlay = NO;
	location = 0;
	spawn = @"0";
	die = @"0";
	max = 0;
	initdraw = NO;
	dragging = NO;
	backColor = [NSColor blackColor];
}

- (id)initWithFrame:(NSRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
		frameRect = [self bounds];
		prevRect = frameRect;
		lastevent = 0;
		graphColor = [NSColor blackColor];
		rawData = [[NSMutableArray alloc] init];
		graphData = [[NSMutableArray alloc] init];
		dataPath = [[NSBezierPath alloc] init];
		overlayPath = nil;
		[self initPart];
	}
    return self;
}

- (NSBezierPath*) drawPath:(NSMutableArray*) data andArgs:(NSString*)args{
	NSBezierPath* path;
	int i;
	int nextx = 0;
	int nexty = 7;
	path = [[NSBezierPath alloc] init];
	[path setLineWidth:1];
	[path moveToPoint:NSMakePoint(nextx, nexty)];
	if ([data count] > 0) {
		for (i = 0; i < [data count]; i++) {
			nextx = i;
			float value = [[[data objectAtIndex:i] objectAtIndex:0] floatValue];
			float logv;
			if (value == 0) {
				logv = 0.0;
			}
			else if (value == 1) {
				logv = 0.5;
			}
			else {
				logv = logf(value);
			}
			float logm = logf(max);
			nexty = 7 + ((logv/logm)*(frameRect.size.height-7));
			[path lineToPoint:NSMakePoint(nextx, nexty)];
		}
	}
	[path lineToPoint:NSMakePoint(nextx, 7)];
	[path lineToPoint:NSMakePoint(frameRect.size.width, 7)];
	[path closePath];
	[self setNeedsDisplay:YES];
	return path;
}

- (void) drawGraph:(NSMutableArray*) data andArgs:(NSString*) args {
	if ([args isEqualToString:@"data"]) {
		dataPath = [self drawPath:data andArgs:args];
	}
	else if ([args isEqualToString:@"overlay"]) {
		overlayPath = [self drawPath:data andArgs:args];
	}
}

- (NSMutableArray*)makeStats:(NSMutableArray*) data {
	NSMutableArray* vals = [[NSMutableArray alloc] init];
	int i;
	int lastev = (frameRect.size.width);
	int numev = (lastevent) / (lastev -1 );
	for (i = 0; i < lastev; i++) {
		NSMutableArray* vals_element = [NSMutableArray arrayWithCapacity:2];
		[vals_element addObject:[NSNumber numberWithInt:0]];
		[vals_element addObject:@"0"];
		[vals addObject:vals_element];
	}
	for (i = 0; i < [data count]; i++) {
		NSString* event = [data objectAtIndex:i];
		int event_pos = [event intValue] / numev;
		int avg = [event intValue];
		NSString* avg_str = [NSString stringWithFormat:@"%d", avg];
		[[vals objectAtIndex:event_pos] replaceObjectAtIndex:1 withObject:avg_str];
		int update = [[[vals objectAtIndex:event_pos] objectAtIndex:0] intValue] + 1;
		[[vals objectAtIndex:event_pos] replaceObjectAtIndex:0 withObject:[NSNumber numberWithInt:update]];
		if (update > max) {
			max = update;
		}
	}
	if (max == 1) {
		max++;
	}
	return vals;
}

- (void)loadData:(NSMutableArray*)data andLast:(int)last andColor:(NSColor*)color andBackground:(NSColor*)bcolor {
	[self initPart];
	backColor = bcolor;
	graphColor = color;
	lastevent = last;
	rawData = data;
	graphData = [self makeStats:data];
}

- (void)drawRect:(NSRect)rect {
	frameRect = [self bounds];
	if ((initdraw == NO) && (lastevent > 0)) {
		[self drawGraph:graphData andArgs:@"data"];
		initdraw = YES;
	}
	if (![self inLiveResize]) {
		if (prevRect.size.width != frameRect.size.width) {
			[self viewDidEndLiveResize];
		}
	}
	[backColor set];
	NSRectFill(rect);
	[graphColor set];
	[dataPath fill];
	if (overlay) {
		[self drawGraph:graphOverlayData andArgs:@"overlay"];
		[[NSColor redColor] set];
		[overlayPath fill];
	}
	
	NSBezierPath* base = [[NSBezierPath alloc] init];
	[base setLineWidth:1.0];
	[base moveToPoint:NSMakePoint(0,7)];
	[base lineToPoint:NSMakePoint(frameRect.size.width, 7)];
	[[NSColor whiteColor] set];
	[base stroke];
	
	NSString* stats = [NSString stringWithFormat:@"%d / %d", found, [rawData count]];
	NSMutableAttributedString *s = [[NSMutableAttributedString alloc] initWithString:stats];
	[s addAttribute:NSFontAttributeName	value:[NSFont userFontOfSize:9] range:NSMakeRange(0,[s length])];
	[s addAttribute:NSForegroundColorAttributeName value:[NSColor blackColor] range:NSMakeRange(0,[s length])];
	NSString *last = [stats lastPathComponent];
	int range_l = [stats length] - [last length] - 1;
	[s addAttribute:NSForegroundColorAttributeName value:[NSColor redColor] range:NSMakeRange(0, range_l)];
	NSRect text = NSMakeRect(0, frameRect.size.height-10, 100, 10);
	[s drawInRect:text];
}

/*- (BOOL)isOpaque { 
    return [[NSColor whiteColor] alphaComponent] >= 1.0 ? YES : NO;
}*/

- (void) viewDidEndLiveResize {
	graphData = [self makeStats:rawData];
	graphOverlayData = [self makeStats:rawOverlayData];
	[self drawGraph:graphData andArgs:@"data"];
	[self drawGraph:graphOverlayData andArgs:@"overlay"];
	[self setNeedsDisplay:YES];
}

- (void) notifyMatched:(NSMutableArray*) matched andQuery:(BOOL)query {
	found = [matched count];
	NSMutableArray* matchedArray = [NSMutableArray arrayWithCapacity:found];
	if (query) {
		int i;
		for (i = 0; i < found; i++) {
			[matchedArray addObject:[[matched objectAtIndex:i] valueForKey:@"timestamp"]];
		}
		overlay = YES;
		rawOverlayData = matchedArray;
		graphOverlayData = [self makeStats:matchedArray];
	}
	else {
		overlay = NO;
		found = 0;
	}
}

@end
